package com.spbdx.system.sysdict.support;

import com.spbdx.common.core.domain.entity.SysDictData;
import com.spbdx.common.core.domain.entity.SysDictType;
import com.spbdx.common.utils.PackageUtil;
import com.spbdx.common.utils.StringUtils;
import com.spbdx.system.mapper.SysDictDataMapper;
import com.spbdx.system.mapper.SysDictTypeMapper;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Set;

/**
 * Description 系统字典初始化
 *
 * @author chenwei
 * @version 1.0
 * @date 2023/3/13 16:44
 */
@Component
public class DictCodeInitializer implements ApplicationRunner {

    private Logger log = LoggerFactory.getLogger(DictCodeInitializer.class);

    @Resource
    private SysDictTypeMapper dictTypeMapper;

    @Resource
    private SysDictDataMapper dictDataMapper;

    private static final String SCAN_PACKAGE = "com.spbdx";

    @Override
    public void run(ApplicationArguments args) {
        try {
            if (log.isInfoEnabled()) {
                log.info("---------------------系统字典初始化开始！--------------------------");
            }
            this.init();
            if (log.isInfoEnabled()) {
                log.info("---------------------系统字典初始化结束！--------------------------");
            }
        } catch (Exception e) {
            if (log.isErrorEnabled()) {
                log.error("系统字典初始化失败：{}", e.getMessage());
            }
        }
    }

    /**
     * 初始化
     */
    @Transactional
    public void init() {
        Set<Class> classes = PackageUtil.scanClasses(SCAN_PACKAGE, DictionaryCategory.class);
        if (ObjectUtils.isNotEmpty(classes)) {
            classes.forEach(obj -> {
                DictionaryCategory typeAnno = (DictionaryCategory) obj.getAnnotation(DictionaryCategory.class);
                String typeCode = typeAnno.value().name().toLowerCase();
                String typeName = typeAnno.value().getLabel();
                SysDictType sysDictType = dictTypeMapper.checkDictTypeUnique(typeCode);
                if (ObjectUtils.isEmpty(sysDictType)) {
                    sysDictType = new SysDictType();
                    sysDictType.setDictType(typeCode);
                    sysDictType.setDictName(typeName);
                    sysDictType.setStatus("0");
                    sysDictType.setCreateBy("admin");
                    sysDictType.setCreateTime(new Date());
                    sysDictType.setIsSystem("1");
                    dictTypeMapper.insertDictType(sysDictType);
                }
                if (DictionaryCode.class.isAssignableFrom(obj) && obj.isEnum()) {
                    String simpleName = obj.getName();
                    //反射获取枚举类
                    Class<Enum> clazz = null;
                    try {
                        clazz = (Class<Enum>) Class.forName(simpleName);
                        //获取所有枚举实例
                        Enum[] enumConstants = clazz.getEnumConstants();
                        Method getLabel = clazz.getMethod("getLabel");
                        for (Enum enum1 : enumConstants) {
                            //得到枚举name()
                            String code = enum1.name().toLowerCase();
                            //执行枚举方法获得枚举实例对应的值
                            Object label = getLabel.invoke(enum1);
                            SysDictData sysDictData = new SysDictData();
                            sysDictData.setDictLabel(String.valueOf(label));
                            sysDictData.setDictValue(code);
                            sysDictData.setDictType(typeCode);
                            sysDictData.setStatus("0");
                            String dictLabel = dictDataMapper.selectDictLabel(typeCode, code);
                            if (StringUtils.isBlank(dictLabel)) {
                                dictDataMapper.insertDictData(sysDictData);
                            }
                            if (StringUtils.isNotBlank(dictLabel) && !dictLabel.equals(label)) {
                                dictDataMapper.updateDictData(sysDictData);
                            }
                        }
                    } catch (ClassNotFoundException | NoSuchMethodException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
}
